#include <stdlib.h>
#include "stm32f10x.h"
#include "bsp.h"
#include "app.h"

#define WEAK    __attribute__ ((weak))


/* provided by the linker script */

extern unsigned long _etext;    /* end VMA/LMA address of the text section */
extern unsigned long _sldata;   /* start LMA address of the data section */
extern unsigned long _sdata;    /* start VMA address of the data section */
extern unsigned long _edata;    /* end VMA address of the data section */
extern unsigned long _sbss;     /* start VMA address of the bss section */
extern unsigned long _ebss;     /* end VMA address of the bss section */
/* the VMA address of the bottom of the stack */
extern unsigned long _user_stack_start;


static void initial_data(void);

extern void WEAK _init(void);
extern void WEAK _fini(void);
extern void __libc_init_array(void);
extern void __libc_fini_array(void);
extern int main(void);


static void initial_data(void)
{
    unsigned long *src, *dst;

    /* copy the .data section into RAM */
    src = &_sldata;
    dst = &_sdata;
    if (src != dst)
        while(dst < &_edata)
            *(dst++) = *(src++);

    /* zero the .bss section */
    dst = &_sbss;
    while(dst < &_ebss)
        *(dst++) = 0;
}

#pragma weak Reset_Handler = _start
void _start(void)
{
    initial_data();

    /* the offset to the vector table in ROM */
    extern uint32_t _isr_vectors_start[];
    /* set interrupt vector table address */
    SCB->VTOR = (uint32_t)_isr_vectors_start;

    atexit(__libc_fini_array);
    __libc_init_array();

    SystemInit(); /* configure the clock */

    hardware_init_hook();
    software_init_hook();

    exit(main()); /* start execution of the program */
    while(1) {}
}

#pragma weak _init              = empty_function
#pragma weak _fini              = empty_function
static void empty_function(void)
{
}

